import java.util.concurrent.CountDownLatch;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: Ap0stoL2
 * Date: 2023-08-03
 * Time: 22:48
 */


//CountDownLatch
public class Demo29 {
    public static void main(String[] args) throws Exception {
        //构造方法中,指定要创建几个任务,这里是10个
        CountDownLatch latch = new CountDownLatch(10);

        for (int i = 0; i < 10; i++) {

            int finalI = i;//当前的i是外面的,打印的i是在线程的回调函数lambda函数种,所以lambda捕获的变量要是final或者不变的
            Thread t = new Thread(()->{
                System.out.println("线程 "+ finalI +" 开始工作");
                try {
                    //用sleep 代表耗时操作,比如下载
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("线程 "+ finalI +" 结束工作!");

                // latch.countDown();就相当于 100米田径比赛 的其中一个运动员撞线了,我们初始化的是10,所以相当于10个运动员,10个运动员都撞线就结束了
                latch.countDown();//相当于计数器--

            });
            t.start();
        }

        //主线程如何知道上述任务都完成了吗?
        //难道要用10次join方法吗
        //万一要任务结束,但是main线程不结束,那么join就没法用了
        //主线程中使用 latch.await(); 阻塞等待所有任务执行完毕
        // 当countDown次数小于初始化设置的次数就会一直阻塞,直到任务>=初始化次数才会结束阻塞
        latch.await();
        System.out.println("多个线程的所有任务都结束了");



         //runnanble写法
//        Runnable r = new Runnable() {
//            @Override
//            public void run() {
//                try {
//                    Thread.sleep((long) (Math.random() * 10000));
//                    latch.countDown();
//                } catch (Exception e) {
//                    e.printStackTrace();
//                }
//            }
//        };
//        for (int i = 0; i < 10; i++) {
//            new Thread(r).start();
//        }
//
//        latch.await();
//        System.out.println("比赛结束");


    }
}
